﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIT.Controls.Data;
using UIT.Controls.Containers;
using UIT.Controls;
using System.Xml;
using UIT.Controls.Template;
using UIT.Web.Controls.Data;
using UIT.Web.Controls.Template;
using UIT.Web.Controls.Html;
using JQueryControlToolkit;

namespace UIT.Web.Renderers
{
    public class DataGridRenderer : WebControlRenderer<DataGrid>, IControlRenderer<DataGrid.Row>
    {
        public override void Render(DataGrid control)
        {
            if (control.DataGridColumns.All(columns => control.ShouldRenderOnClient(columns.ItemTemplate)))
            {
                if (string.IsNullOrEmpty(control.Id))
                    throw new ArgumentNullException("Id", "The id cannot be null when a control is meant to be used on a client side");
                IClientDataProvider clientDataProvider = control.DataSource as IClientDataProvider;

                StringBuilder sb = new StringBuilder();
                using (XmlWriter writer = XmlWriter.Create(sb, this.writer.Settings))
                {
                    var manager = new WebRendererManager(writer);
                    writer.WriteStartElement("tr");

                    foreach (Column column in control.DataGridColumns)
                    {
                        IControl emptyColumn = column.ItemTemplate.Template.CreateInstance();
                        writer.WriteStartElement("td");
                        IControlRenderer itemTemplateRenderer = manager.Manager.Control.GetRenderer(emptyColumn);
                        ((IWebRenderer)itemTemplateRenderer).RunAt = RunAtMode.Client;

                        itemTemplateRenderer.Render(column.ItemTemplate.Template.CreateInstance());
                        writer.WriteEndElement();
                    }
                    writer.WriteEndElement();
                    writer.Flush();
                    if (clientDataProvider == null)
                    {
                        //should fall in that case only for EnumerableDataProvider
                        ScriptManager.RegisterCall("datagrid" + control.Id, JQueryControlToolkit.JQuery.Tmpl(sb.ToString(), control.DataSource.Select(new SelectArgument())).AppendTo("#" + control.Id));
                    }
                    else
                        ScriptManager.RegisterCall("datagrid" + control.Id, JQueryControlToolkit.JQuery.Tmpl(sb.ToString(), clientDataProvider.Render()).AppendTo("#" + control.Id));
                }


                this.writer.WriteStartElement("input");
                this.writer.WriteAttributeString("name", control.Id);
                this.writer.WriteAttributeString("type", "hidden");
                this.writer.WriteEndElement();

                this.writer.WriteStartElement("table");
                control.RenderFullStyle(this.writer, "datagrid");
                this.writer.WriteAttributeString("id", control.Id);
                this.writer.WriteFullEndElement();
            }
            else
            {
                this.writer.WriteStartElement("input");
                this.writer.WriteAttributeString("name", control.Id);
                this.writer.WriteAttributeString("type", "hidden");
                this.writer.WriteEndElement();

                this.writer.WriteStartElement("table");
                if (!string.IsNullOrEmpty(control.Id))
                    this.writer.WriteAttributeString("id", control.Id);
                control.RenderFullStyle(writer, "datagrid", "ui-state-default");
                if (control.DataGridColumns.Any(col => col.HeaderTemplate != null))
                {
                    writer.WriteStartElement("thead");
                    foreach (var column in control.DataGridColumns)
                    {
                        writer.WriteStartElement("th");
                        writer.WriteAttributeString("class", "ui-widget-header");
                        if (!string.IsNullOrEmpty(column.SortExpression))
                            writer.WriteAttributeString("data-sort", column.SortExpression);
                        Manager.Render(column.HeaderTemplate.CreateInstance(control.DataContext));
                        writer.WriteFullEndElement();
                    }
                    writer.WriteFullEndElement();
                }

                foreach (IContainer row in control.Children)
                    this.RenderControl(row);

                writer.WriteStartElement("tfoot");
                this.RenderPaging(control);
                writer.WriteFullEndElement();


                this.writer.WriteFullEndElement();
            }
        }

        private void RenderPaging(DataGrid control)
        {
            writer.WriteStartElement("tr");
            writer.WriteStartElement("td");
            writer.WriteAttributeString("colspan", "99");
            writer.WriteAttributeString("class", "pager ui-widget-header");
            writer.WriteStartElement("table");
            writer.WriteAttributeString("cellspacing", "2");
            writer.WriteStartElement("tr");
            writer.WriteStartElement("td");
            writer.WriteAttributeString("class", "ui-state-default");
            writer.WriteStartElement("a");
            writer.WriteAttributeString("href", "javascript:" + new JQuery("#" + control.Id).CallPlugIn("JQuery:Datagrid", "datagrid", "prev"));
            writer.WriteAttributeString("class", "prev");
            writer.WriteString("<<");
            writer.WriteFullEndElement();
            writer.WriteFullEndElement();

            for (int i = 1; i <= Math.Ceiling(1.0 * control.TotalRowCount / control.PageSize); i++)
            {
                writer.WriteStartElement("td");
                if (i == control.PageIndex + 1)
                    writer.WriteAttributeString("class", "ui-state-default ui-state-active");
                else
                    writer.WriteAttributeString("class", "ui-state-default");
                writer.WriteStartElement("a");
                writer.WriteAttributeString("href", "javascript:" + new JQuery("#" + control.Id).CallPlugIn("JQuery:Datagrid", "datagrid", "page-" + i));
                writer.WriteString(i.ToString());
                writer.WriteFullEndElement();
                writer.WriteFullEndElement();
            }
            writer.WriteStartElement("td");
            writer.WriteAttributeString("class", "ui-state-default");
            writer.WriteStartElement("a");
            writer.WriteAttributeString("href", "javascript:" + new JQuery("#" + control.Id).CallPlugIn("JQuery:Datagrid", "datagrid", "next"));
            writer.WriteAttributeString("class", "next");
            writer.WriteString(">>");
            writer.WriteFullEndElement();
            writer.WriteFullEndElement();

            writer.WriteFullEndElement();
            writer.WriteFullEndElement();

            writer.WriteFullEndElement();
            writer.WriteFullEndElement();
        }

        void IControlRenderer.Render(UIT.Controls.IControl child)
        {
            if (child.Type == ControlType.TableRow)
                Render(child as DataGrid.Row);
            else

                Render(child as DataGrid);
        }

        public void Render(DataGrid.Row row)
        {
            writer.WriteStartElement("tr");
            row.RenderFullStyle(writer, row.Index % 2 == 0 ? "even" : "ui-state-default odd");
            foreach (IControl column in row.Children)
            {
                writer.WriteStartElement("td");

                Manager.Control.GetRenderer(column).Render(column);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }
    }
}
